#include "memory.h"

char* memcpy (char* destination, const char* source , unsigned int size)
{
	
	for(unsigned int i=0; i<size; i++)
	{
		*destination = *source;
		destination++;
		source++;
	}
	
	return destination;
}

int init_dedicated_memory()
{
	allocation_table_entry* alloc = (allocation_table_entry*)KERNEL_ALLOCATION_TABLE_START;
	
	alloc->type = HEADER_ENTRY;
	alloc->size = 2;								// On cree un header, qui contient le nombre de blocs dans la table.
	
	alloc++;
	
	alloc->type = FREE_ENTRY;
	alloc->size = KERNEL_ALLOCATION_TABLE_SIZE;		// On assigne toute la memoire en tant que libre.
	
	alloc++;
	
	alloc->type = NULL_ENTRY;						// Entree nulle.
	alloc->size = 0x00000000;
	
	return 0;
}

void* malloc(unsigned int size)
{
	allocation_table_entry* header = (allocation_table_entry*)KERNEL_ALLOCATION_TABLE_START;
	allocation_table_entry* alloc = (allocation_table_entry*)(KERNEL_ALLOCATION_TABLE_START + sizeof(allocation_table_entry));
	char* allocation = 0x00000000;
	char* current_mem = (char*)KERNEL_MEMORY_POOL_START;
	unsigned int nbp = 0;
	
	while(!(allocation))
	{
		if(alloc->type == FREE_ENTRY && alloc->size >= size)		// Si on a trouvé un emplacement assez grand
		{
			// On recopie les entrees dans un buffer.
			memcpy((char*)KERNEL_ALLOCATION_BUFFER_START, (char*)(KERNEL_ALLOCATION_TABLE_START + sizeof(allocation_table_entry)*(nbp+1)), (header->size - nbp) * sizeof(allocation_table_entry));
			
			// On insere notre entree
			alloc->type = ALLOCATED_ENTRY;
			alloc->size = size;
			
			// On reinsere les anciennes entrees
			memcpy((char*)(KERNEL_ALLOCATION_TABLE_START + sizeof(allocation_table_entry)*(nbp+2)), (char*)KERNEL_ALLOCATION_BUFFER_START, (header->size - nbp) * sizeof(allocation_table_entry));
			header->size++;
			
			alloc++;
			
			//On dimminue la mémoire libre
			alloc->size -= size;
			
			// On alloue
			
			allocation = current_mem;
			
			
		}
		else
		{
			current_mem += alloc->size;
			nbp++;
			alloc++;												// Si l'emplacement n'est pas assez grand, on cherche encore.
		}
	}
	
	return allocation;
}